package com.cugbmao.lucene;

import java.io.IOException;

import junit.framework.TestCase;

import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;

import com.cugbmao.lucene.util.TestUtil;

public class IndexingTest extends TestCase
{
	protected String[]	ids			= { "1", "2" };
	protected String[]	unindexed	= { "Netherlands", "Italy" };
	protected String[]	unstored	= { "Amsterdam has lots of bridges",
			"Venice has lots of canals" };
	protected String[]	text		= { "Amsterdam", "Venice" };

	private Directory	directory;

	@Override
	protected void setUp() throws Exception
	{
		directory = new RAMDirectory();

		IndexWriter writer = getWriter();

		for (int i = 0; i < ids.length; i++)
		{
			Document doc = new Document();
			doc.add(new StringField("id", ids[i], Field.Store.YES));
			doc.add(new StringField("country", unindexed[i], Field.Store.NO));
			doc.add(new TextField("contents", unstored[i], Field.Store.NO));
			doc.add(new StringField("city", text[i], Field.Store.YES));
			writer.addDocument(doc);
		}
		writer.close();
	}

	private IndexWriter getWriter() throws IOException
	{
		IndexWriterConfig iwf = new IndexWriterConfig(Version.LUCENE_43,
				new WhitespaceAnalyzer(Version.LUCENE_43));
		return new IndexWriter(directory, iwf);
	}

	protected int getHitCount(final String fieldName, final String SearchString)
			throws IOException
	{
		IndexReader reader = DirectoryReader.open(directory);
		IndexSearcher searcher = new IndexSearcher(reader);
		Term t = new Term(fieldName, SearchString);
		Query query = new TermQuery(t);
		int hitCount = TestUtil.hitCount(searcher, query);
		reader.close();
		return hitCount;
	}

	public void testIndexWriter() throws IOException
	{
		IndexWriter writer = getWriter();
		assertEquals(ids.length, writer.numDocs());
		writer.close();
	}

	public void testIndexReader() throws IOException
	{
		IndexReader reader = DirectoryReader.open(directory);
		assertEquals(ids.length, reader.maxDoc());
		assertEquals(ids.length, reader.numDocs());
		reader.close();
	}

	public void testDeleteBeforeOptimize() throws IOException
	{
		IndexWriter writer = getWriter();
		assertEquals(2, writer.numDocs());
		writer.deleteDocuments(new Term("id", "1"));
		writer.commit();
		assertTrue(writer.hasDeletions());
		assertEquals(2, writer.maxDoc());
		assertEquals(1, writer.numDocs());
		writer.close();
	}

	public void testDeleteAfterOptimize() throws IOException
	{
		IndexWriter writer = getWriter();
		assertEquals(2, writer.numDocs());
		writer.deleteDocuments(new Term("id", "1"));
		writer.forceMergeDeletes();
		writer.commit();
		assertFalse(writer.hasDeletions());
		assertEquals(1, writer.maxDoc());
		assertEquals(1, writer.numDocs());
		writer.close();
	}

	public void testUpdate() throws IOException
	{
		assertEquals(1, getHitCount("city", "Amsterdam"));
		IndexWriter writer = getWriter();

		Document doc = new Document();
		doc.add(new StringField("id", "1", Field.Store.YES));
		doc.add(new StringField("country", "Netherlands", Field.Store.NO));
		doc.add(new TextField("contents", "Den Haag has a lot of museums",
				Field.Store.NO));
		doc.add(new StringField("city", "Den Haag", Field.Store.YES));

		writer.updateDocument(new Term("id", "1"), doc);

		writer.close();

		assertEquals(0, getHitCount("city", "Amsterdam"));
		assertEquals(1, getHitCount("city", "Den Haag"));

	}
}
